package org.bugjail.dataaccess.jdbc.objects;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import org.bugjail.data.TestCycle;
import org.bugjail.data.TestReport;
import org.bugjail.dataaccess.DAOFactory;
import org.bugjail.dataaccess.jdbc.connection.QueryException;
import org.bugjail.dataaccess.jdbc.connection.QueryManager;
import org.bugjail.dataaccess.objects.TestCycleDAO;
import org.bugjail.dataaccess.objects.TestReportDAO;

public class JDBCTestCycleDAO implements TestCycleDAO {

	private final String PROPERTIES_FILE = "/org/bugjail/dataaccess/jdbc/properties/testcycledao.properties";

	private final String PROPERTY_RETRIEVE_BY_TESTREPORT = "retrieve.bytestreport";
	private final String PROPERTY_RETRIEVE_BY_ID = "retrieve.byid";
	private final String PROPERTY_INSERT = "insert";
	private final String PROPERTY_UPDATE = "update";
	
	private TestCycle extractTestCycleFromResultSet(ResultSet rs, QueryManager queryManager, TestReport testReport) throws SQLException {
		TestCycle testCycle = new TestCycle();
		int id = rs.getInt("id");
		testCycle.setId(id);

		if (testReport == null) {
			TestReportDAO testReportDao = DAOFactory.getDAOFactory().getTestReportDAO();
			testCycle.setTestReport(testReportDao
					.retrieveById(rs.getInt("testreport_id")));
		} else {
			testCycle.setTestReport(testReport);
		}
		testCycle.setName(rs.getString("name"));
		try {testCycle.setCreation(rs.getDate("creation"));} catch (Exception e) {testCycle.setCreation(null);}
		try {testCycle.setStart(rs.getDate("start"));} catch (Exception e) {testCycle.setStart(null);}
		try {testCycle.setFinish(rs.getDate("finish"));} catch (Exception e) {testCycle.setFinish(null);}
		testCycle.setInstructions(rs.getString("instructions"));

		return testCycle;
	}
	
	@Override
	public List<TestCycle> retrieveTestCyclesOfTestReport(TestReport testReport) {
		List<TestCycle> testCycles = new LinkedList<TestCycle>();
		QueryManager queryManager = null;
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_RETRIEVE_BY_TESTREPORT);
				statement.setInt(1, testReport.getId());
				ResultSet rs = statement.executeQuery();
				while (rs.next()) {
					testCycles.add(extractTestCycleFromResultSet(rs,
							queryManager, testReport));
				}
			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			throw new QueryException(e.getMessage());
		}
		return testCycles;
	}

	@Override
	public void create(TestCycle element) {
		QueryManager queryManager = null;
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_INSERT);
				statement.setString(1, element.getName());
				statement.setInt(2, element.getTestReport().getId());
				statement.setString(3, element.getInstructions());
				statement.executeUpdate();

				QueryManager.commit(queryManager);

			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			QueryManager.rollback(queryManager);
			throw new QueryException(e.getMessage());
		}
	}

	@Override
	public void delete(TestCycle element) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public List<TestCycle> retrieveAll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public TestCycle retrieveById(int id) {
		TestCycle testCycle = null;
		QueryManager queryManager = null;
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_RETRIEVE_BY_ID);
				statement.setInt(1, id);
				ResultSet rs = statement.executeQuery();
				if (rs.next()) {
					testCycle = extractTestCycleFromResultSet(rs, queryManager, null);
				}
			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			throw new QueryException(e.getMessage());
		}
		return testCycle;
	}

	@Override
	public List<TestCycle> retrieveByName(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void update(TestCycle element) {
		QueryManager queryManager = null;
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_UPDATE);
				statement.setString(1, element.getName());
				statement.setInt(2, element.getTestReport().getId());
				statement.setString(3, element.getInstructions());
				statement.setInt(4, element.getId());
				statement.executeUpdate();

				QueryManager.commit(queryManager);

			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			QueryManager.rollback(queryManager);
			throw new QueryException(e.getMessage());
		}
	}

}
